/*
 * Static.cpp
 *
 *  Created on: 2014. 7. 17.
 *      Author: mega
 */

#include "../Static.h"
#include "../Ack.h"
#include "../Enum.h"
#include "../ChannelServer.h"


#include <vector>
#include <Database/Static.h>
#include <Logger/Static.h>


namespace GuildServer {

Static::Static() : m_GuildPool(1000), m_MemberPool(20000)
{
	m_bTest = false;
}

Static::~Static()
{

}

bool
Static::AddGuild(std::shared_ptr<Guild> pGuild)
{
	auto iter = m_GuildTree.find(pGuild->GetSeq());
	if (iter != m_GuildTree.end())
		return false;

	m_GuildTree[pGuild->GetSeq()] = pGuild;

	return true;
}

bool
Static::DelGuild(uint32_t guildSeq)
{
	auto iter = m_GuildTree.find(guildSeq);
	if (iter == m_GuildTree.end())
		return false;

	m_GuildTree.erase(iter);

	// TODO : Redis 삭제

	return true;
}

std::shared_ptr<Guild>
Static::GetGuild(uint32_t guildSeq)
{
	auto iter = m_GuildTree.find(guildSeq);
	if (iter == m_GuildTree.end())
	{
		return NULL;
	}

	return iter->second;
}

std::shared_ptr<Guild>
Static::LoadGuild( uint32_t guild_seq )
{
	std::shared_ptr<Guild> pGuild = Static::Instance().NewGuild();
	if ( NULL == pGuild )
		return std::shared_ptr<Guild>(NULL);
		//return NULL;

	pGuild->Initialize( 0, guild_seq );
	int eRes = pGuild->LoadData( guild_seq );
	if( ACK_OK != eRes )
		return std::shared_ptr<Guild>(NULL);

	if ( AddGuild( pGuild ) )
	{
		m_kRankList.UpdatePoint( guild_seq, pGuild->GetData()._score );

		return pGuild;
	}

	return std::shared_ptr<Guild>(NULL);
}


void
Static::LoadRecommendedGuilds()
{
	std::vector<uint32_t> vecGuild;

	// 길드 정보 loading
	{
		Database::ResultSet res = Database::Execute(static_cast<int>(DatabaseType::GUILD_MASTER), "call sp_select_guild_recommand_list()");

		if (0 != res.GetSQLError())
		{
			LOG(ERR, __FUNCTION__, " : Fail call sp_select_guild_recommand_list");
			return;
		}

		if (0 == res.GetRowCount())
		{
			LOG(ERR, __FUNCTION__, " : not exists guild");
			return;
		}

		for (Database::ResultSet::iterator iter = res.begin(); iter != res.end(); iter++)
		{
			vecGuild.push_back( iter->getInt("guild_seq")); // result
		}
	}

	//int iPoint = 1;
	auto iter = vecGuild.begin();
	for ( ; iter != vecGuild.end(); ++iter )
	{
		LoadGuild( *iter );

		// TODO 랭킹 테스트 용도
		//m_kRankList.UpdatePoint( *iter, iPoint++ );
	}

	m_kRankList.GetList(1); // 1 page에 대한 정보를 미리 생성해둔다.
}


std::shared_ptr<Guild>
Static::NewGuild()
{
	return m_GuildPool.Create();
}

std::shared_ptr<Member>
Static::NewMember()
{
	return m_MemberPool.Create();
}


void
Static::AddChannelServer( ChannelServer* a_pSession )
{
	if ( NULL == a_pSession )
		return;

	uint32_t iKey = a_pSession->GetSessionKey();
	m_ChannelServerTree[iKey] = a_pSession;

	LOG(DEV, __FUNCTION__, "> Added a channel server.> session key: ", a_pSession->GetSessionKey(), ", channel key: ", a_pSession->GetChannelKey());
}


void
Static::DelChannelServer( int a_iSessionKey )
{
	auto iter = m_ChannelServerTree.find(a_iSessionKey);
	if (iter == m_ChannelServerTree.end())
		return;

	m_ChannelServerTree.erase(iter);

	LOG(DEV, __FUNCTION__, "> Deleted a channel server.> session key: ", a_iSessionKey);
}

void
Static::BroadcastChatMsgToChannelServerAll(const BroadcastGuildChatAck& msg)
{
	LOG(DEV, __FUNCTION__, "> sender: ", msg.nickname.c_str(), ", chat: ", msg.chat.c_str());

	auto iter = m_ChannelServerTree.begin();
	for ( ; iter != m_ChannelServerTree.end(); ++iter )
	{
		ChannelServer* pServer = iter->second;
		if ( NULL == pServer )
			continue;

		LOG(DEV, __FUNCTION__, "> \tTo channel server> session key: ", pServer->GetSessionKey(), ", channel key: ", pServer->GetChannelKey());
		pServer->SendMsg( msg );
	}
}

//template <class MSG> void
//Static::BroadcastMsgToChannelServerAll(const MSG& msg)
//{
//	//LOG(DEV, __FUNCTION__, "> sender: ", msg.nickname.c_str(), ", chat: ", msg.chat.c_str());
//
//	auto iter = m_ChannelServerTree.begin();
//	for ( ; iter != m_ChannelServerTree.end(); ++iter )
//	{
//		ChannelServer* pServer = iter->second;
//		if ( NULL == pServer )
//			continue;
//
//		//LOG(DEV, __FUNCTION__, "> \tTo channel server> session key: ", pServer->GetSessionKey(), ", channel key: ", pServer->GetChannelKey());
//		pServer->SendMsg( msg );
//	}
//}


} /*GuildServer*/




